#include "config.h"

#include <iostream>
#include <memory>
#include <string>
#include <vector>
#if CFG_HAVE_STD_RANGES
#include <ranges>
#endif

using namespace cfg;

// 作用：打印对象数组中每个元素的 id 与 v 字段，若缺失则以占位输出。
// 参数：
//   v - 指向包含 "objs" 数组的根视图。
// 返回：无。
static void
print_objs_array(View & v)
{
    auto objs = v.lookup("objs");
    if (!objs.has_value())
    {
        std::cout << "objs: <missing>\n";
        return;
    }
    auto av = objs->array_view();
    if (!av.has_value())
    {
        std::cout << "objs: <not-array>\n";
        return;
    }
    std::cout << "objs.size=" << av->size() << "\n";
    // 遍历索引
    for (size_t i = 0; i < av->size(); ++i)
    {
        const Value & it = (*av)[i];
        auto pobj = std::get_if<std::shared_ptr<const Object>>(&it);
        if (pobj && *pobj)
        {
            View ov(*pobj);
            auto id = ov.lookup("id");
            auto vv = ov.lookup("v");
            std::cout << "  - id=";
            if (id.has_value())
            {
                auto sid = id->get_string();
                std::cout << (sid.has_value() ? *sid : std::string("?"));
            }
            else
            {
                std::cout << "<missing>";
            }
            std::cout << ", v=";
            if (vv.has_value())
            {
                auto iv = vv->get_int64();
                std::cout << std::to_string(iv.has_value() ? iv.value() : int64_t(-1));
            }
            else
            {
                std::cout << "<missing>";
            }
            std::cout << "\n";
        }
        else
        {
            std::cout << "  - <not-object>\n";
        }
    }
}

// 作用：构造一对用于数组合并演示的对象根：
//   dst: { nums:[1,2,3], objs:[{"id":"a","v":1},{"id":"b","v":2}] }
//   src: { nums:[2,3,4], objs:[{"id":"b","v":20},{"id":"c","v":30}] }
// 返回：pair(dst, src)
static std::pair<Object, Object>
make_roots()
{
    auto dst_nums = std::make_shared<Array>();
    dst_nums->items.push_back(int64_t{1});
    dst_nums->items.push_back(int64_t{2});
    dst_nums->items.push_back(int64_t{3});

    auto obj_a = std::make_shared<Object>();
    obj_a->props["id"] = std::string("a");
    obj_a->props["v"] = int64_t{1};
    auto obj_b = std::make_shared<Object>();
    obj_b->props["id"] = std::string("b");
    obj_b->props["v"] = int64_t{2};

    auto dst_objs = std::make_shared<Array>();
    dst_objs->items.push_back(std::shared_ptr<const Object>(obj_a));
    dst_objs->items.push_back(std::shared_ptr<const Object>(obj_b));

    Object dst_root;
    dst_root.props["nums"] = std::shared_ptr<const Array>(dst_nums);
    dst_root.props["objs"] = std::shared_ptr<const Array>(dst_objs);

    auto src_nums = std::make_shared<Array>();
    src_nums->items.push_back(int64_t{2});
    src_nums->items.push_back(int64_t{3});
    src_nums->items.push_back(int64_t{4});

    auto obj_b2 = std::make_shared<Object>();
    obj_b2->props["id"] = std::string("b");
    obj_b2->props["v"] = int64_t{20};
    auto obj_c = std::make_shared<Object>();
    obj_c->props["id"] = std::string("c");
    obj_c->props["v"] = int64_t{30};

    auto src_objs = std::make_shared<Array>();
    src_objs->items.push_back(std::shared_ptr<const Object>(obj_b2));
    src_objs->items.push_back(std::shared_ptr<const Object>(obj_c));

    Object src_root;
    src_root.props["nums"] = std::shared_ptr<const Array>(src_nums);
    src_root.props["objs"] = std::shared_ptr<const Array>(src_objs);

    return {std::move(dst_root), std::move(src_root)};
}

// 作用：演示 Overwrite/Append/Deduplicate/Keyed 四种数组合并策略的直观效果。
// 返回：无。
static void
run_array_merge_demos()
{
    // 1) Overwrite：源数组替换目标
    {
        auto [dst_root, src_root] = make_roots();
        Builder b;
        b.set_merge_strategy(MergeStrategy::Deep)
            .set_array_merge_strategy(ArrayMergeStrategy::Overwrite)
            .merge_object(dst_root)
            .merge_object(src_root);
        auto fr = b.freeze();
        if (!fr.has_value())
        {
            std::cout << "Overwrite failed\n";
            return;
        }
        View v(*fr);
        auto nums = v.lookup("nums");
        auto av = nums->array_view();
        std::cout << "[Overwrite] nums=";
        if (av.has_value())
        {
            // C++17 输出：以逗号分隔
            for (size_t i = 0; i < av->size(); ++i)
            {
                if (i > 0)
                    std::cout << ",";
                std::cout << std::get<int64_t>((*av)[i]);
            }
            std::cout << "\n";
        }
    }

    // 2) Append：目标后追加源
    {
        auto [dst_root, src_root] = make_roots();
        Builder b;
        b.set_merge_strategy(MergeStrategy::Deep)
            .set_array_merge_strategy(ArrayMergeStrategy::Append)
            .merge_object(dst_root)
            .merge_object(src_root);
        auto fr = b.freeze();
        if (!fr.has_value())
        {
            std::cout << "Append failed\n";
            return;
        }
        View v(*fr);
        auto nums = v.lookup("nums");
        auto av = nums->array_view();
        std::cout << "[Append] nums=";
        if (av.has_value())
        {
            for (size_t i = 0; i < av->size(); ++i)
            {
                if (i > 0)
                    std::cout << ",";
                std::cout << std::get<int64_t>((*av)[i]);
            }
            std::cout << "\n";
        }
    }

    // 3) Deduplicate：追加并去重
    {
        auto [dst_root, src_root] = make_roots();
        Builder b;
        b.set_merge_strategy(MergeStrategy::Deep)
            .set_array_merge_strategy(ArrayMergeStrategy::Deduplicate)
            .merge_object(dst_root)
            .merge_object(src_root);
        auto fr = b.freeze();
        if (!fr.has_value())
        {
            std::cout << "Deduplicate failed\n";
            return;
        }
        View v(*fr);
        auto nums = v.lookup("nums");
        auto av = nums->array_view();
        std::cout << "[Deduplicate] nums=";
        if (av.has_value())
        {
            for (size_t i = 0; i < av->size(); ++i)
            {
                if (i > 0)
                    std::cout << ",";
                std::cout << std::get<int64_t>((*av)[i]);
            }
            std::cout << "\n";
        }
    }

    // 4) Keyed：对象数组按 id 合并
    {
        auto [dst_root, src_root] = make_roots();
        Builder b;
        b.set_merge_strategy(MergeStrategy::Deep)
            .set_array_merge_strategy(ArrayMergeStrategy::Keyed)
            .set_array_merge_key("id")
            .merge_object(dst_root)
            .merge_object(src_root);
        auto fr = b.freeze();
        if (!fr.has_value())
        {
            std::cout << "Keyed failed\n";
            return;
        }
        View v(*fr);
        std::cout << "[Keyed] ";
        print_objs_array(v);
    }
}

// 作用：程序入口，调用 run_array_merge_demos 演示数组合并策略。
// 返回：0 表示正常结束。
int
main()
{
    run_array_merge_demos();
    return 0;
}
